home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / util / time / Stardate.lha / stardate.c < prev   
C/C++ Source or Header  |  1994-12-19  |  5KB  |  166 lines

  1. /*************************************************************
  2.  * File:             stardate.c
  3.  * Author:           Jay Windley  (modified by Yves Perrenoud)
  4.  * Created:           1 Jan 92    (modified 19 Dec 94)
  5.  * Copyright:        (c)  1 Jan 92 by Jay Windley
  6.  * Description:      prints the current stardate to stdout
  7.  *
  8.  *************************************************************/
  9.  
  10. #include <stdio.h>
  11. #include <sys/types.h>
  12. #include <time.h>
  13.  
  14. #define    FIT(x,y) while((x)<0)(x)+=(y);while((x)>(y))(x)-=(y)
  15.  
  16. #define MAXPRECISION       7
  17. #define OUTPUTFORMAT       "%%%03d.%df"
  18.  
  19. /*---------------------------------------------------------------------*
  20.  *TAG (                           julian_day                           );
  21.  *---------------------------------------------------------------------*
  22.  * Returns the New Epoch Julian Day for the given Gregorian calendar
  23.  * day.
  24.  */
  25. double julian_day (month, day, year)
  26.      int month, day, year;
  27. {
  28.   int loc_month;
  29.   int loc_year;
  30.   int a, b, c, d;
  31.   
  32.   loc_month = month;
  33.   loc_year = year;
  34.   
  35.   /* correct for March-based B.C. year */
  36.   if (year < 0) loc_year ++;
  37.   if (month < 3) {
  38.     loc_month = month + 12;
  39.     loc_year --;
  40.   }
  41.   
  42.   /* set up A and B for Julian to Gregorian calendar change */
  43.   if (year < 1582) b = 0;
  44.   else if (year == 1582) {
  45.     if (month < 10) b = 0;
  46.     else if (month == 10) {
  47.       if (day < 15) b = 0;
  48.       else {
  49.     a = loc_year / 100;
  50.     b = 2 - a + (a/4);
  51.       }
  52.     } else {
  53.       a = loc_year / 100;
  54.       b = 2 - a + (a/4);
  55.     }
  56.   } else {
  57.     a = loc_year / 100;
  58.     b = 2 - a + (a/4);        /* century is set up */
  59.   }
  60.   
  61.   /* fudge for year and month */
  62.   c = (int) (365.25 * loc_year) - 694025;
  63.   d = (int) (30.6001 * (loc_month + 1));
  64.   
  65.   return (double) (b + c + d + day) - .5;
  66. }
  67.  
  68. /*---------------------------------------------------------------------*
  69.  *TAG (                            sidereal                            );
  70.  *---------------------------------------------------------------------*
  71.  * Returns Greenwich Mean Sidereal Time for the given Greenwich Mean
  72.  * Solar Time on the given NE Julian Day.
  73.  */
  74. double sidereal (gmt, jd, gyear)
  75.      double gmt;        /* Greenwich Mean Time, decimal    */
  76.      double jd;            /* Julian Day */
  77.      int gyear;            /* calendar year */
  78. {
  79.   register double dayfudge, yrfudge, jhund;
  80.   double initjd, hourfudge, time0, lst;
  81.   
  82.   /* find Julian century at start of year */
  83.   initjd = julian_day (1, 0, gyear);
  84.   jhund = initjd / 36525.0;
  85.   
  86.   /* apply polynomial correction */
  87.   dayfudge = 6.6460656 + (0.051262 + (jhund * 0.00002581)) * jhund;
  88.   yrfudge = 2400.0 * (jhund - ( (double) (gyear - 1900) / 100));
  89.   hourfudge = 24.0 - dayfudge - yrfudge;
  90.   time0 = (jd - initjd) * 0.0657098 - hourfudge;
  91.   
  92.   /* adjust to modulo 24 hours */
  93.   lst = (gmt * 1.002737908) + time0;
  94.   FIT (lst, 24.0);
  95.   return lst;
  96. }
  97.  
  98. /*---------------------------------------------------------------------*
  99.  *TAG (                              main                              );
  100.  *---------------------------------------------------------------------*
  101.  * Behaves as expected.
  102.  */
  103. void main (argc, argv)
  104.      int argc;
  105.      char *argv[];
  106. {
  107.   int timezone=0,i;
  108.   int jd, precis;
  109.   double gmt, gmst;
  110.   time_t t;
  111.   struct tm *tm;
  112.   char buf[16];
  113.   char fmt[16];
  114.  
  115. /* Parsing below rewritten by Yves Perrenoud based on the original code */
  116.  
  117.      if (argc > 1)
  118.      {
  119.         for (i=1;i <= (argc-1);i++)
  120.         {
  121.             if (argv[i][0] == '-')
  122.             {
  123.                 switch (argv[i][1])
  124.                 {
  125.                     case 'd' :    if (sscanf (&argv[i][2], "%d", &precis) < 1)
  126.                                 {
  127.                                     fprintf (stderr, "%s: invalid precision specification\n", argv[0]);
  128.                                     exit (1);
  129.                                 }
  130.                                 if (precis < 1) precis = 1;
  131.                                 if (precis > MAXPRECISION) precis = MAXPRECISION;
  132.                                 break;
  133.                     case 't' :    if (sscanf (&argv[i][2], "%d", &timezone) < 1)
  134.                                 {
  135.                                     fprintf (stderr, "%s: invalid timezone specification\n", argv[0]);
  136.                                     exit (1);
  137.                                 }
  138.                                 if (timezone < -12) timezone = -12;
  139.                                 if (timezone > 12) timezone = 12;
  140.                                 break;
  141.                     case 'h' :  puts("options:");
  142.                                 puts("  -d<prec> : precision from 1 to 7");
  143.                                 puts("  -t<tz>   : timezone from -12 to 12");
  144.                                 exit(0);
  145.                                 break;
  146.                     default  : puts("Uknown type of OPTION"); exit(1);
  147.                 }
  148.             }
  149.         }
  150.     } else precis = 1;
  151.  
  152.  
  153. /* timezone modifications made by Yves Perrenoud for Amiga compatibility */
  154.  
  155.   t = time (NULL);
  156.   tm = localtime (&t);
  157.   jd = julian_day (tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
  158.   gmt = (double) tm->tm_hour - timezone +
  159.     tm->tm_min / 60.0 +
  160.     tm->tm_sec / 3600.0;
  161.   gmst = sidereal (gmt, (double) jd, tm->tm_year);
  162.   sprintf (fmt, OUTPUTFORMAT, precis + 6, precis);
  163.   sprintf (buf, fmt, (double) jd + gmst / 24.0);
  164.   puts (buf);
  165. }
  166.